from Common.EventHandle import EventHandle

from Calendar.Calendar import *
from Misc.QuoteType import *
from FinancialAsset.AssetFactory import *
from Technical.TechnicalIndicator import *
from DataFeeder.QueryDailyBar import query_index_bar

from Config.TradeCost import *


class IndexMAFollow(EventHandle):
	
	def __init__(self, index_list, start_date, end_date, 
				short_sma_len, long_sma_len, atr_len, trd_units):
		
		self.trd_units = trd_units
		
		cld = TradingCalendar(['CNSESH'])
		data_start = cld.offset_by_business_days(start_date, max(long_sma_len,atr_len), forward = False)
		data_dates = cld.date_series(data_start, end_date, Frequency.Daily)
		
		self.daily_bar = query_index_bar(data_dates, index_list)
		closs_array = self.daily_bar.value_array(field_list = ['CLOSE'])
		hlc_array = self.daily_bar.value_array(field_list = ['HIGH', 'LOW', 'CLOSE'])
		
		s_ma = SimpleMovingAverage(closs_array, short_sma_len)
		l_ma = SimpleMovingAverage(closs_array, long_sma_len)
		atr = AverageTrueRange(hlc_array, atr_len)

		self.daily_bar.add_field(['SHORT_SMA'], s_ma)
		self.daily_bar.add_field(['LONG_SMA'], l_ma)
		self.daily_bar.add_field(['ATR'], atr)
		self.daily_bar.del_field(['OPEN', 'HIGH', 'LOW', 'RETURN', 'VOLUME', 'AMOUNT'])
		
		monitor_dates = [d for d in data_dates if d >= start_date]
		monitor_dates.sort()
		
		EventHandle.__init__(self, monitor_dates)
		
	def create_activities(self, ref_date, portf = None):
	
		t_index = self.daily_bar.time_index([ref_date])
		pre_date = self.daily_bar.time_list()[t_index[0] - 1]
		
		holding = portf.holding(ref_date)
		nav = portf.nav(ref_date)
		if nav <= 0:
			print 'warning - nav <= 0'
		
		activities = []
		for ticker in self.daily_bar.security_list():
		
			pre_sma = self.daily_bar.value_array([pre_date], [ticker], ['SHORT_SMA'])[0][0][0]
			pre_lma = self.daily_bar.value_array([pre_date], [ticker], ['LONG_SMA'])[0][0][0]
			sma = self.daily_bar.value_array([ref_date], [ticker], ['SHORT_SMA'])[0][0][0]					
			lma = self.daily_bar.value_array([ref_date], [ticker], ['LONG_SMA'])[0][0][0]	
			close = self.daily_bar.value_array([ref_date], [ticker], ['CLOSE'])[0][0][0]
			atr = self.daily_bar.value_array([ref_date], [ticker] ,['ATR'])[0][0][0]
				
			trd_num = self.trd_units * round(0.01 * nav / atr)
				
			index = AssetFactory().acquire_asset('INDEX', ticker)
			cash = AssetFactory().acquire_asset('CASH', index.currency())
				
			if (pre_sma-pre_lma) < 0 and (sma-lma) > 0:
					
				if holding.has_key(index):
				
					if holding[index] < 0:								
						buy_num = -holding[index] + trd_num
						activities.append((ref_date, index, buy_num))
						activities.append((ref_date, cash, -buy_num*close*(1+STOCK_TRADE_COST)))
				else:
					activities.append((ref_date, index, trd_num))
					activities.append((ref_date, cash, -trd_num*close*(1+STOCK_TRADE_COST)))

			elif (pre_sma-pre_lma) > 0 and (sma-lma) < 0:
				
				if holding.has_key(index):
				
					if holding[index] > 0:
						sell_num = holding[index] + trd_num
						activities.append((ref_date, index, -sell_num))
						activities.append((ref_date, cash, sell_num*close*(1-STOCK_TRADE_COST)))
					else:
						activities.append((ref_date, index, -trd_num))
						activities.append((ref_date, cash, trd_num*close*(1-STOCK_TRADE_COST)))
			else:
				pass
		
		return activities
		
	@staticmethod	
	def event_name():
		return 'IndexMAFollow'
			
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		




